#ifndef LEDDAYDRIVER_H
#define LEDDAYDRIVER_H
#include "softwarePwm.h"
#include "EEPROMHelperFunc.h"
#define UPDATE_PERIOD 1000
#define MILLISINDAY 86400000
struct DayParams
{
unsigned char min;
unsigned char max;
unsigned long daystarttime;
unsigned long daylengthtime;
unsigned long timeAdjustment;
DayParams readFromEeprom(unsigned char addr)
{
    DayParams retval = {};
    retval.daystarttime = EEPROMHelpers::readLongFromEeprom(addr);
    addr+= sizeof(retval.daystarttime);
    retval.daylengthtime = EEPROMHelpers::readLongFromEeprom(addr);
    addr+= sizeof(retval.daylengthtime);
    retval.min = EEPROM.read(addr++);
    retval.max = EEPROM.read(addr);

}
void writeToEeprom(unsigned char startAddr)
{
    EEPROMHelpers::writeToEeprom(startAddr, daystarttime);
    startAddr += sizeof(daystarttime);
    EEPROMHelpers::writeToEeprom(startAddr,daylengthtime);
    startAddr += sizeof(daylengthtime);
    EEPROM.write(startAddr++, min);
    EEPROM.write(startAddr, max);
}
};

class LEDDayDriver : public TimerEventListener
{
public:
    LEDDayDriver( TimerQueue& militimer, TimerQueue& microtimer, DayParams pday, PWMParams pwm)
        :ledpin(microtimer, pwm), timer(militimer), day(pday)

    {
        adjustPwm();
        timer.registerTimerEvent(this,UPDATE_PERIOD);
    }
    unsigned long onTime()
    {
        adjustPwm();
        return UPDATE_PERIOD;
    }

    void setDayConfig(const DayParams& pday)//add getter and rework to use DayParams structure
    {
        day = pday;
    }
    DayParams getDayConfig()
    {
        return day;
    }
private:
    void adjustPwm()
    {
        unsigned char newState = day.min;
        unsigned long currentTime = (millis()+day.timeAdjustment)%MILLISINDAY;//modulo miliseconds in 24h
        if(currentTime < day.daystarttime+day.daylengthtime && currentTime > day.daystarttime)
        {
             newState = day.min+(day.max-day.min)*(((-1.*cos(2.*PI * (double)(currentTime - day.daystarttime)/(double)day.daylengthtime))+1)/2);
        }
        if(newState != currentState)
        {
          ledpin.setPWM(newState);
          if(newState==0)
            ledpin.stop();
          if(currentState==0)
            ledpin.start();  
          currentState = newState;
        }


    }
    Pwm ledpin;
    TimerQueue& timer;
    DayParams day;
    unsigned char currentState;
};

#endif // LEDDAYDRIVER_H
